package com.example.toy.core.conf;

import com.example.toy.core.partition.HivePartitionPathStyle;
import com.example.toy.core.record.key.generator.CombineKeyGenerator;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * ToyConfigs
 *
 * @author shenbing
 * @date 2021/12/17
 */
public enum ToyConfigs {
  TOY_SYSTEM_TYPE("toy.system.type", null, "toy system type"),
  TOY_SYSTEM_NAME("toy.system.name", null, "toy system name"),

  ARCHIVED_ENABLED("toy.archived.enabled", false, "is archive table"),
  TABLE_NAME("toy.table.name", null, "table name"),

  DATA_DIR("toy.data.dir", null, "table data dir"),

  TABLE_SCHEMA("toy.table.schema", null, "table schema"),
  PARTITION_FIELDS("toy.table.partition.fields", null, "table name"),
  PARTITION_KEY_GENERATOR(
      "toy.partition.key.generator",
      CombineKeyGenerator.class.getCanonicalName(),
      "partition key generator"),

  PARTITION_PATH_STYLE_GENERATOR(
      "toy.partition.key.generator",
      HivePartitionPathStyle.class.getCanonicalName(),
      "partition key generator"),

  PRIMARY_KEY_FIELDS("toy.record.key.fields", null, "table name"),

  KEY_GENERATOR("toy.record.key.generator", "", "");

  public static final Map<String, String> defaults;

  static {
    java.util.Map<String, String> properties = new HashMap<>();
    for (ToyConfigs value : ToyConfigs.values()) {
      if (value.defaultValue != null) {
        properties.put(value.key, String.valueOf(value.defaultValue));
      } else {
        properties.put(value.key, "");
      }
    }
    defaults = Collections.unmodifiableMap(properties);
  }

  private final String key;
  private final Object defaultValue;
  private final String doc;
  private final boolean immutable;

  ToyConfigs(String key, Object defaultValue, String doc, boolean immutable) {
    this.key = key;
    this.defaultValue = defaultValue;
    this.doc = doc;
    this.immutable = immutable;
  }

  ToyConfigs(String key, Object defaultValue, String doc) {
    this(key, defaultValue, doc, true);
  }

  public String read(Map<String, ?> properties) {
    Object value = properties.containsKey(this.key) ? properties.get(this.key) : this.defaultValue;
    return value == null ? null : String.valueOf(value);
  }

  public String getKey() {
    return key;
  }

  public Object getDefaultValue() {
    return defaultValue;
  }

  public String getDoc() {
    return doc;
  }

  public boolean isImmutable() {
    return immutable;
  }

  public String getDefaultValueAsString() {
    return (String) defaultValue;
  }
}
